package cn.boodqian.d3surveyor;

import java.util.ArrayList;

import cn.boodqian.util.Log;

import android.content.Context;
import android.database.Cursor;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Spinner;
import android.widget.ImageView;
import android.widget.TextView;

class Colors {
	// static public int LEAGENT = Color.parseColor("#948064");
	static public int LEAGENT = Color.parseColor("#ae6c3a");
	static public int RARE    = Color.parseColor("#f1f121");
	static public int BLUE    = Color.parseColor("#6f6fcc");
	static public int LIGHTBLUE = Color.parseColor("#99D9EA");
	static public int GRAY    = Color.parseColor("#CCCCCC");
	static public int WHITE   = Color.parseColor("#ffffff");
}

public class MagicPropertyFragment extends Fragment implements OnItemSelectedListener, OnItemClickListener {

	private D3DB mDB;
	private Spinner mSpinnerPart;
	private Spinner mSpinnerEquip;
	private ImageView mItemImage;
	private ListView mListMagicProperty;
	private ListView mListSelectedMagicProperty;
	private ArrayList<Long> mSelectedPropertyList = new ArrayList<Long>();
	private ArrayList<Integer> mSelectedLevelList = new ArrayList<Integer>();
	
	private int m_SpinnerCount = 2;
	private int m_SelectCount = 0;

	private class ColorCursorAdapter extends SimpleCursorAdapter {
		public ColorCursorAdapter(Context context, int layout, Cursor c,
				String[] from, int[] to) {
			super(context, layout, c, from, to);
		}
		
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			View view = super.getView(position, convertView, parent);
			
			Cursor c = getCursor();
			c.moveToPosition(position);
			
			final int id = c.getInt(c.getColumnIndex("_id"));
			final int viewId = parent.getId();
			final int level = c.getInt(c.getColumnIndex("l_type"));
			int m_type = c.getInt(c.getColumnIndex("m_type"));
			// String minvalue = c.getString(c.getColumnIndex("minvalue"));
			String maxvalue = c.getString(c.getColumnIndex("maxvalue"));
			
			TextView t1 = (TextView) view.findViewById(R.id.text_magic_range);
			TextView t2 = (TextView) view.findViewById(R.id.text_magic_level);
			CheckBox t = (CheckBox) view.findViewById(R.id.check_magic_name);

			switch(viewId) {
				case R.id.list_magic_property:
					t.setChecked(false); //Any check will remove from list, so always unchecked
					break;
				case R.id.list_selected_magic_property:
					t.setChecked(true); //Any uncheck will remove from list, so always checked
					break;
			}
			
			// set text
			String tmp;
			if (mDB.isMagicPercentage(m_type)) {
				tmp = " (max: "+maxvalue+"%)";
			} else {
				tmp = " (max: "+maxvalue+")";
			}
			t.setText(mDB.getNameByType(mDB.m_mTypeCursor, m_type)+tmp);
			// t2.setText(mDB.getNameByType(mDB.m_lTypeCursor, level));
			t1.setText("");
			t2.setText("");
			
			t1.setTextColor(Colors.WHITE);
			if(level<=10) {
				t.setTextColor(Colors.LEAGENT);
				t1.setTextColor(Colors.LEAGENT);
			}
			else if(level<=20) {
				t.setTextColor(Colors.RARE);
				t1.setTextColor(Colors.RARE);
			}
			else if (level <=30) {
				t.setTextColor(Colors.BLUE);
				// t2.setTextColor(Colors.BLUE);
				t1.setTextColor(Colors.BLUE);
			} else if (level <=40) {
				t.setTextColor(Colors.LIGHTBLUE);
				t1.setTextColor(Colors.LIGHTBLUE);
			} else {
				// Have to reset since we may be re-using item view
				t.setTextColor(Colors.GRAY);
				t1.setTextColor(Colors.GRAY);
			}

			t.setOnCheckedChangeListener(new OnCheckedChangeListener() {
				public void onCheckedChanged(CompoundButton buttonView,	boolean isChecked) {
					switch(viewId) {
					case R.id.list_magic_property:
						if (!isChecked) return;
						Log.i("select "+id);
						mSelectedPropertyList.add((long) id);
						mSelectedLevelList.add(Integer.valueOf(level));
						updatePropertyList();
						updateScore();
						break;
					case R.id.list_selected_magic_property:
						if (isChecked) return;
						Log.i("deselect "+id);
						mSelectedPropertyList.remove(Long.valueOf(id));
						mSelectedLevelList.remove(Integer.valueOf(level));
						updatePropertyList();
						updateScore();
						break;
					}
				}
			});
			return view;
		}
	}

	private ColorCursorAdapter mAdapter=null;
	private ColorCursorAdapter mSelectedAdapter=null;
	
	private class EquipScore {
		
		public int getScore() {
			int score = 0;
			float s = 0;
			float upper = 600;
			for (Integer i : mSelectedLevelList) {
				// use reciprocal
				if (i.intValue() == 40) {
					s += 1.0 / 30.0;
				} else {
					s += 1.0 / i.floatValue();
				}
			}
			score = (int)(s * upper);
			return score;
		}
		
		/*
		 * 190 +  golden
		 * 120 - 189  rare
		 * 60 - 119   blue
		 * 0  - 59    white
		 */
		public int getScoreColor(int score) {
			if (score >= 190) {
				return Colors.LEAGENT;
			} else if (score>=120) {
				return Colors.RARE;
			} else if (score>=60) {
				return Colors.BLUE;
			} else {
				return Colors.WHITE;
			}
		}
	}
	
	private EquipScore m_score = new EquipScore();
	
	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		
		mDB = D3DB.getInstance(getActivity());

		mSpinnerPart = (Spinner)getActivity().findViewById(R.id.spinner_part);
		mSpinnerEquip = (Spinner)getActivity().findViewById(R.id.spinner_equipment);
		mSpinnerPart.setAdapter(mDB.cursorToAdapter(mDB.m_epTypeCursor, R.layout.part_spinner));
		
		mSpinnerPart.setOnItemSelectedListener(this);
		mSpinnerEquip.setOnItemSelectedListener(this);
		
		mItemImage = (ImageView)getActivity().findViewById(R.id.image_item);
		
		mListSelectedMagicProperty = (ListView) getActivity().findViewById(R.id.list_selected_magic_property);
		mListMagicProperty = (ListView) getActivity().findViewById(R.id.list_magic_property);
		mListSelectedMagicProperty.setOnItemClickListener(this);
		mListMagicProperty.setOnItemClickListener(this);
		
		//onChangeProfession(mDB.getProfessionType());
		
		// we need draw all items
		// draw part spinner
		updatePartSpinner();
		// set and update equip spinner
		setUpdateEquipmentSpinner();
		// image
		updateItemImage();
		// list and score
		rebuildPropertyList();
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		return inflater.inflate(R.layout.magicproperty_fragment, container, false);
	}

	public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
			long arg3) {
		if(m_SelectCount<m_SpinnerCount) {
			m_SelectCount++;
			Log.i("select count="+m_SelectCount);
			return;
		}
		Log.i("eptype="+mDB.getPartType()+",etype="+mDB.getEquipmentType()+",ptype="+mDB.getProfessionType());
		
		Cursor e = null;
		switch(arg0.getId()) {
		case R.id.spinner_part:
			mSelectedPropertyList.clear();
			mSelectedLevelList.clear();
			e = (Cursor) arg0.getItemAtPosition(arg2);
			int epType = mDB.getCursorType(e);
			if (mDB.getPartType() == epType) break;
			onChangePart(epType);
			break;
		case R.id.spinner_equipment:
			mSelectedPropertyList.clear();
			mSelectedLevelList.clear();
			e = (Cursor) arg0.getItemAtPosition(arg2);
			int eType = mDB.getCursorType(e);
			if (mDB.getEquipmentType() == eType) break;
			onChangeEquipment(eType);
			break;
		}
	}
	
	private void updateUI() {
		// update UI, using mPType, mEPType, mEType
		Log.i("eptype="+mDB.getPartType()+",etype="+mDB.getEquipmentType()+",ptype="+mDB.getProfessionType());
		
		updatePartSpinner();
		updateEquimentSpinner();
		updateItemImage();
		rebuildPropertyList();
	}
	
	/*
	 *  event \ action |  part spinner |  equip spinner | image   | list and score  | profession
	 * ------------------------------------------------------------------------------------------
	 *  page1 ->       |  set & update |  set & update  |  update |    rebuild      |     no
	 *  language       |     update    |     update     |   no    |    rebuild      |   update
	 *  profession     |      no       |  set & update  |  update |    rebuild      |     no
	 *  part spinner   |      no       |  set & update  |  update |    rebuild      |     no
	 *  equip spinner  |      no       |      no        |  update |    rebuild      |     no
	 *  resume         |      no       |      no        |   no    |       no        |     no
	 */

	public void updateLang() {
		mSpinnerPart.setAdapter(mDB.cursorToAdapter(mDB.m_epTypeCursor, R.layout.part_spinner));
		mSpinnerEquip.setAdapter(mDB.cursorToAdapter(mDB.m_eTypeCursor, R.layout.equip_spinner));
		// update part
		updatePartSpinner();
		// update equipment
		updateEquimentSpinner();
		// list and score
		rebuildPropertyList();
	}
	
	public void onChangeProfession(int pType) {	
		// if (mDB.getProfessionType() == pType) return;
		mDB.setProfessionType(pType);
		
		// update part spinner, if is empty
		if (mDB.getPartType() == 0) {
			updatePartSpinner();
		} 
		// set and update equip spinner
		setUpdateEquipmentSpinner();
		// image
		updateItemImage();
		// list and score
		rebuildPropertyList();
	}

	public void onChangePart(int epType) {
		// if (mDB.getPartType() == epType) return;
		mDB.setPartType(epType);
		// set and update equip spinner
		setUpdateEquipmentSpinner();
		// image
		updateItemImage();
		// list and score
		rebuildPropertyList();
	}

	public void onChangeEquipment(int eType) {
		// even the eType is the same, we should refresh the list
		mDB.setEquipmentType(eType);
		// image
		updateItemImage();
		// list and score
		rebuildPropertyList();
	}
	
	private void rebuildPropertyList() {
		updatePropertyList();
		updateScore();
		updateBaseProperty();
	}
	
	private void updatePartSpinner() {
		// Select the current choice from ChoosePartFragment for mSpinnerPart
		Log.i("in update part spinner, part="+mDB.getPartType());
		if (mDB.getPartType() == 0) {
			mDB.setPartType(mDB.getDefaultPartType());
		}
		for (int i = 0; i < mSpinnerPart.getCount(); i++) {
			Cursor value = (Cursor) mSpinnerPart.getItemAtPosition(i);
			//Log.i("i="+i+", type="+value.getInt(value.getColumnIndex("type")));
			if( mDB.getPartType() == value.getInt(value.getColumnIndex("type"))) {
				Log.i("in update part spinner, select = "+i);
				mSpinnerPart.setSelection(i, true);
				break;
			}
		}
		Log.i("selected="+mSpinnerPart.getSelectedItemPosition());
	}
	
	private void updateEquimentSpinner() {
		// Select the current choice from ChoosePartFragment for mSpinnerEquipment
		Log.i("equip="+mDB.getEquipmentType());
		for (int i = 0; i < mSpinnerEquip.getCount(); i++) {
			Cursor value = (Cursor) mSpinnerEquip.getItemAtPosition(i);
			//Log.i("i="+i+", type="+value.getInt(value.getColumnIndex("type")));
			if( mDB.getEquipmentType() == value.getInt(value.getColumnIndex("type"))) {
				Log.i("select "+i);
				mSpinnerEquip.setSelection(i, true);
				break;
			}
		}
	}
	
	private void setUpdateEquipmentSpinner() {
		// redraw the equipment spinner, and set the Equip type in mDB
		Cursor c = mDB.selectSubEquipType();
		getActivity().startManagingCursor(c);
		Log.i("count="+c.getCount());
		mSpinnerEquip.setAdapter(mDB.cursorToAdapter(c, R.layout.equip_spinner));
		
		if (mSpinnerEquip.getCount()>=1) {
			Cursor value = (Cursor) mSpinnerEquip.getItemAtPosition(0);
			mDB.setEquipmentType(value.getInt(value.getColumnIndex("type")));
			updateEquimentSpinner();
		} else {
			mDB.setEquipmentType(mDB.getPartType());
		}
	}

	public void onNothingSelected(AdapterView<?> arg0) {

	}

	@Override
	public void onResume() {
		super.onResume();

		//updateUI();
	}
		
	private void updatePropertyList() {
		Cursor cursor = mDB.selectPropertyLevel(mSelectedPropertyList);
		getActivity().startManagingCursor(cursor);
		
		Log.i("all count="+cursor.getCount());
		if(mAdapter==null) {
			mAdapter=new ColorCursorAdapter(getActivity(),
					R.layout.propery_list_item,
					cursor,
					new String[] {"m_type","maxvalue","l_type"},
					new int[]{R.id.check_magic_name, R.id.text_magic_range, R.id.text_magic_level});
			
			mListMagicProperty.setAdapter(mAdapter);
		}
		else {
			mAdapter.changeCursor(cursor);
		}
		
		cursor = mDB.selectSelectedPropertyLevel(mSelectedPropertyList);
		getActivity().startManagingCursor(cursor);
		
		Log.i("selected count="+cursor.getCount());
		if(mSelectedAdapter==null) {
			mSelectedAdapter=new ColorCursorAdapter(getActivity(),
					R.layout.propery_list_item,
					cursor,
					new String[] {"m_type","maxvalue","l_type"},
					new int[]{R.id.check_magic_name, R.id.text_magic_range, R.id.text_magic_level});
			
			mListSelectedMagicProperty.setAdapter(mSelectedAdapter);
		}
		else {
			mSelectedAdapter.changeCursor(cursor);
		}
	}
	
	private void updateItemImage() {
		int drawable_id = mDB.getItemDrawableId();
		if (drawable_id == 0) { return; }
		mItemImage.setImageDrawable(getActivity().getResources().getDrawable(drawable_id));
	}
	
	private void updateScore() {
		TextView t = (TextView)getActivity().findViewById(R.id.text_score);
		int s = m_score.getScore();
		t.setText(String.valueOf(s));
		int c = m_score.getScoreColor(s);
		t.setTextColor(c);
	}
	
	private void updateBaseProperty() {
		Cursor c = mDB.selectBaseProperty();
		getActivity().startManagingCursor(c);
		TextView t = (TextView)getActivity().findViewById(R.id.text_baseProperty);
		if (c.getCount() == 0) {
			t.setText("");
			return;
		}
		c.moveToLast();
		do {
			int maxvalue = c.getInt(c.getColumnIndex("maxvalue"));
			if (maxvalue>0) {
				int m_type = c.getInt(c.getColumnIndex("m_type"));
				String min_value = c.getString(c.getColumnIndex("minvalue"));
				String max_value = c.getString(c.getColumnIndex("maxvalue"));
				String magic_name = mDB.getNameByType(mDB.m_mTypeCursor, m_type);
				t.setText(magic_name+" ("+min_value+"-"+max_value+")");
				return;
			}
		} while(c.moveToPrevious());
		t.setText("");
	}

	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
		Cursor c = (Cursor)parent.getItemAtPosition(position);
		getActivity().startManagingCursor(c);
		int level = c.getInt(c.getColumnIndex("l_type"));
		switch(parent.getId()) {
		case R.id.list_magic_property:
			Log.i("select "+id);
			mSelectedPropertyList.add(Long.valueOf(id));
			mSelectedLevelList.add(Integer.valueOf(level));
			updatePropertyList();
			updateScore();
			break;
		case R.id.list_selected_magic_property:
			Log.i("deselect "+id);
			mSelectedPropertyList.remove(Long.valueOf(id));
			mSelectedLevelList.remove(Integer.valueOf(level));
			updatePropertyList();
			updateScore();
			break;
		}
	}
}
